from __future__ import absolute_import
import logging

from django.views.decorators.csrf import csrf_exempt

from sentry.api.base import Endpoint

from sentry.integrations.atlassian_connect import AtlassianConnectValidationError, get_integration_from_jwt
from sentry.models import sync_group_assignee_inbound

logger = logging.getLogger('sentry.integrations.jira.webhooks')


def handle_assignee_change(integration, data):
    assignee_changed = any(
        item for item in data['changelog']['items'] if item['field'] == 'assignee'
    )
    if not assignee_changed:
        return

    fields = data['issue']['fields']

    # if no assignee, assume it was unassigned
    assignee = fields.get('assignee')
    issue_key = data['issue']['key']

    if assignee is None:
        sync_group_assignee_inbound(
            integration, None, issue_key, assign=False,
        )
        return

    if not assignee.get('emailAddress'):
        logger.info(
            'missing-assignee-email', extra={
                'issue_key': issue_key,
                'integration_id': integration.id,
            }
        )
        return

    sync_group_assignee_inbound(
        integration, assignee['emailAddress'], issue_key, assign=True
    )


def handle_status_change(integration, data):
    status_changed = any(
        item for item in data['changelog']['items'] if item['field'] == 'status'
    )
    if not status_changed:
        return

    issue_key = data['issue']['key']

    try:
        changelog = next(
            item for item in data['changelog']['items'] if item['field'] == 'status'
        )
    except StopIteration:
        logger.info(
            'missing-changelog-status', extra={
                'issue_key': issue_key,
                'integration_id': integration.id,
            }
        )
        return

    for org_id in integration.organizations.values_list('id', flat=True):
        installation = integration.get_installation(org_id)

        installation.sync_status_inbound(issue_key, {
            'changelog': changelog,
            'issue': data['issue'],
        })


class JiraIssueUpdatedWebhook(Endpoint):
    authentication_classes = ()
    permission_classes = ()

    @csrf_exempt
    def dispatch(self, request, *args, **kwargs):
        return super(JiraIssueUpdatedWebhook, self).dispatch(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        try:
            token = request.META['HTTP_AUTHORIZATION'].split(' ', 1)[1]
        except (KeyError, IndexError):
            return self.respond(status=400)

        try:
            integration = get_integration_from_jwt(
                token, request.path, 'jira', request.GET, method='POST'
            )
        except AtlassianConnectValidationError:
            return self.respond(status=400)

        data = request.data

        if not data.get('changelog'):
            logger.info(
                'missing-changelog', extra={
                    'integration_id': integration.id,
                }
            )
            return self.respond()

        handle_assignee_change(integration, data)
        handle_status_change(integration, data)

        return self.respond()
